Go进阶训练营 第二课
2021年11月4日 更新
开启更多功能,提升办公效能



  1. 最近团队在做微服务框架选型,主要在比较 go-kit,dubbo-go,go-micro 这几个,业务场景是物联网平台和运维平台,可能会进行私有化部署,想请教毛老师对微服务框架选择有什么建议。<首先需要确定是否有历史包袱,如果有 java 包袱,那么 dubbo-go 较为合适,若是新项目可以考虑 go-kit,go-micro 目前版本变动比较大不太建议,另外可以关注一下 go-zero,kratos,go-chassis,另物联网通常需要 mqtt,paho 系列的客户端比较不错>
  1. BFF 层定义的 API 多种多样,比如一个根据订单 id 查询、一个根据用户&时间等多种多样的维度。SERVICE 层如何兼容各个 BFF API?<接口单一原则,尽量保证一个接口只做一件事,但你的例子:订单 id,用户,时间 这一看就是订单服务,所以肯定是一个订单 service(至少是订单数据查询维度的服务就基本可以了,不要再拆了)>
  1. 关于 gRPC 的 proto 文件维护的最佳实践是怎么样的?比如说 rpc 的调用方和被调用方都要在代码库维护一份 proto 文件的代码吗<统一 repo 维护,可通过一些 ci 工具触发对应项目 hook 进行具体语言的代码生成>
  1. 目前是做 java 开发,想转到 go,但是感觉看 go 的文档比较不习惯,有没有什么快速入门能够先从简单项目上手的方法?刚参加工作不就,很多分布式方面的知识都不懂,对于后面要讲到的内容想做一下预习,建议看一些什么?<熟悉一门语言,首先就是了解其语法特征,而官方文档是最准确的资料。其次第一课推荐过一些基础学习的知识用例,可以完整了解整个语法特性,然后就是多看一些优秀的项目了解别人实现的方法以及流行的风格,第一课讲了从单体到分布式的演变过程>
  1. 学习的总结是推荐放在哪里或者什么工具归档<onenote、有道笔记、语雀、git 都可以,一定要有总结沉淀出自己的内容>
  1. proto buffer 改动后如何做到多端共享
  1. 据我现在在做的事情而言,直接把 pb 文件给其他端就行
  1. gRPC 的强约束是指什么,有什么作用

语言约束,都通过 pb 定义接口。字段变更,下游使用的服务都需要更新。 作用:对比 restful

  1. health check 一般多少的频率,ping 啥频率

ping 就是 health 的一种方式吧。一般是分钟级别,加上可容忍的心跳数,再加上毛老师说的子集算法

  1. 外挂方式和主动方式有什么优劣区别吗

外挂方式就是容器内部服务器起来,就已经往注册中心注册好服务了。代码主动注册。需要多写代码吧

  1. 外挂方式是如何感知到新添加进来的节点的?

外挂方式会订阅注册中心的信息(自己相关的信息),当有新节点添加,会往注册中心注册,就会感知到了。

  1. 服务端发现 LB 可以部署多实例来分摊负载吗?直连的话,重新发布时总有一段时间有客户端流量打过来

可以分多实例。 一般服务发布的时候,可以调整权重来发布,或者用热加载。

  1. 用 eruka 不用 etcd 作服务发现是因为 cp 性能没有 ap 好吗?
    不是因为性能问题,服务发现 ap 更重要些,对于一致性来说,可以用 health check 来相对保证 c。所以选项用了他
  1. eruka 只用做服务发现吗?牺牲了一致性那么相对 consul,etcd 是不是少了作为 kv 存储的功能?
    术业有专攻,可能你了解的 etcd 会拿来做一些存前更新进度,部分文章篇储,但也是轻量级的。
  1. healthcheck 是每台机器 ping 他依赖的所有服务的 ip 列表么?

14.1 先讲为什么要 ping 接口。

例如 http://xxx.com/ping,探测路径/ping 是一个约定,生产服务必须有探活接口。

理由有 2 个,1 保证应用级别存活结果可知,2 响应超时多是资源(cpu/mem)不足导致,k8s 编排保证服务状态最终一致机制(重新拉起实例)恢复业务,重启大法解决可访问问题。也就是说所有服务都有/ping 接口,那服务器上运行的服务 ip 列表都是需要的。

14.2 再讲依赖列表问题。探测分为端到端的探测(服务互调)和集中式探测(LB 类对注册地址的探测)。探测列表,全服务端列表/部分服务端列表。全列表会导致探测量跟调用端成正比,在调用者数量可观的时候,纯探测压力就比较大。毛老师说的子集算法是部分服务端列表,是用 C 端数量,是保证了服务端随机均衡分布覆盖,同时又不必每一个 C 端请求所有的 S 端,降低了服务端探测压力。这个就是个调灵和迟钝的折中,对失败容忍性低的就调短探测时间。健康检查还有种粗粒度的方式就端口探测,网络层的探测,对应用侵入小、消耗小,代价就是没应用级别准确,比如进程夯住就无法发现。

  1. 跨服务分页:两个条件在两个服务的情况怎么操作,没有主题库的情况下(插队可耻)

你看能否解决你的问题 1.某个表做下数据冗余可以解决 2.再做一个表做聚合然后搜索

  1. 老师,cache 更新,你们有个读取处理 binlog 的服务,那么这个服务怎么保证每次能够读取正确的 binlog 点位的,是这个服务会每次记录读取 binlog 点位到 consul 之类的嘛还是怎么处理的

canal 处理 binlog 服务,然后消息写入 kafka,保证消费者处理 kafka 读取是正确的 binlog 点位。

  1. 处理 binlog 的这个服务不能多副本部署吧 否则处理 binlog 会重复吧 如果只是一个服务处理 binlog 会有性能问题吧 -- cannal 同步数据到新~!的数据库,只是同步下数据,还是会做数据清洗??

一般是单实例部署就可以了,消息接到 kafka,由下游的消费者再来处理写入。canal 一般是用来同步数据,如果想处理的话,可以自己在消费者那做清洗逻辑。

  1. 多集群如何保证各个集群间的数据一致性?

集群按是否存储数据可分为无状态集群和有状态集群

处理请求逻辑,但不存储数据的是无状态集群,无需保障数据一致性

可能处理请求逻辑,但一定存储数据的是有状态集群。分布式 CAP 理论,AP 或 CP。CP 有著名的一致性算法,Paxos、Raft

毛老师在课程中好像说到这个问题,更新是通过事件广播的,一次不成功就广播多次直到成功为止,也就是最终一致性

  1. 如果使用服务端发现模式,healthcheck 的性能压力是不是可以减少很多,还需要那个子集算法么?

需要看量级,比如大型的 LB 集群有无意间 healthcheck 就会把低配置实例服务打卦,但小集群就没问题,这个是服务端多到一定程度引起的问题。那个子集算法也是客户端多到一定程度引起的问题,所以不要过早关注性能,这个不管是开发和架构里都是适用的,当然设计的时候也要关注边界,把握好这个度不容易。

  1. 多集群和单集群多节点比有什么优势

故障域隔离程度不一样。物理的单机故障或逻辑故障,影响的范围是你故障的比例。隔离又分物理隔离和逻辑隔离。抗物理风险高,演变成多数据中心多集群;抗逻辑故障,同数据中心多集群。微服务拆分了服务和存储,一定要注意物理上是否隔离(内核现在隔离 cpu、mem 很好,但磁盘 io 和网络 io 不好)。分割的同时会带来管理上的复杂度,按需取舍。

  1. SAAS 平台类的系统,天然支持您说的多租户,我理解的没问题吧?

多租户就是多用户,SAAS 产品从设计的时候就是考虑的不同用户如何使用它部分产品或资源。

考虑资源隔离、审计、计费等。

毛老师在微服务里引进多租户概念是解决资源访问和隔离。

  1. 多租户服务是隔离开来了,但是使用的资源是没有隔离的?如果服务存在 bug,资源没有隔离会影响生产环境吧?
  1. 线上多租户通常指染色、灰度,这个流量通常不会太大,可以在网关配置灰度流量比例
  1. 多集群机制有没有做联邦,有没有做多云厂商的多活呢
  1. 多云一般建议做多可用区,两个云之间通常没有专线相通,多集群可以在同个 AZ 里
  1. context 在父 goroutine 与子 goroutine 之间怎么传递?
  1. 如果需要控制子 goroutine,直接传递进去就可以了
  1. 跨服务分页:两个条件在两个服务的情况怎么操作,没有主题库的情况下,比如:订单时间小于 2019 下单人 性别是女| 这样就 是两个服务(一个 订单  一个用户)我理解那个同学想问这种?

<

  • 出现高度耦合的跨服务分页的话,就得考虑一下设计上是不是有问题了。
  • 跨服务分页的话,我们一般会抽一个全局视野的关联表出来,又或是有数据清洗的相关操作。具体业务具体分析了。

>

  1. 多租户的核心是不是就是,给流量打上不同的标签。如果某些服务需要测试的新功能就专注该标签的流量来进行处理就 ok 了?

<

  • 差不多吧,简单来讲就是注入特定的标识,然后根据该标志进行流量分发等操作,接着就是对应包含该标签的容器应用来进行实际处理。

>

  1. 请问老师微服务经常用到级联故障, 对于这种问题排查有什么可以借鉴的经验么

<

  • 上好全链路追踪,包括日志等把 trace.id 补全,基本没问题。级联故障,做好根因定位,查起来非常快,经过分析后的告警系统都能识别出来。

>

  1. 子集算法没有理解,老师能否在告知下刚才提到的开源代码中哪部分是子集算法。

<////SRE:Google 运维解密 page201>

  1. 容器是通过 macvlan,将容器的网络直接放到物理机所在网络中,通过服务发现拿到 IP 访问的吗?不通过 k8s 的 service 和 ingress 是吗

<容器(例如:Docker)网络,当然不会和 k8s 的 service 和 ingress 产生关联,毕竟最近 k8s 都要 docker 适配他自己的 CRI 了。>

  1. 对于多集群 的那个 cache hit ratio 下降,整个集群全部连接没太听懂 // 缓存击穿


  1. 多租户测试,新建的是新的 mysql 库还是表,还是实例?和生产在同一个 server 上吗

新建的是 shadow 表,在一个 server 上。


  1. 针对 API 请求的站全链路压测可以使用染色方法,如果是针对资源3消耗类型场景的全链路压测,怎么建设压测环境?(比如 B 站怎么做视频投稿/视频播放场景的压测)



  1. 微服务这块,后面会有相应的实践吗

培训有课表,可以留意一下。


  1. 压测的资源隔离怎么做的?机房直接隔离开?


  1. healthcheck 跟子集算法的关系不太理解能讲更具体一点吗?

可以参考老师课上给出的讲解,简单讲两者都是为了使得消费者让自己尽早的从负载均衡池中摘掉,做到平滑下线。

  1. 多租户压测数据是怎么产生?

可以考虑从线上真实数据提取数据做加工(比如去隐私)回灌到生产环境做压力测试。

  1. 公司使用 java 的 springcloud 目前是想用 golang 去慢慢的替换,注册中心使用的 eureka 请问老师我想把 golang 的服务注册到 eureka 应该注意什么。还有后面的逐步迁移有什么需要注意的地方

这个需要毛剑老师来回答一下。

  1. 服务发现能否复用业务请求来避免心跳包开销,即业务请求本身也是一种心跳。也就是说客户端调用服务时,客户端本地对每个请求的响应情况做周期性统计,对于网络问题(超时、网络不可达)或者 5XX 等异常,根据异常比例将对应访问节点的权重适当降低。具体实现的时候,可以做到中间件里面,在 RPC 返回前做统计。这种方式是不是更简单,而且还能减少心跳包的开销,也不需要引入子集选择算法。

Heartbeat 请求相当于 echo,成功的话说明对方一定是活着的,不成功说明对方网络有问题,如果使用业务请求,那么当业务请求失败了,你怎么判断失败是业务本身的问题还是服务器网络问题?另外心跳请求需要定时去发送,业务请求怎么做到?最后业务请求的时间基本都大于心跳请求的时间,这个代替心跳检查给服务器带来的负担太大,浪费计算资源。

  1. redis 溃的时候需要,穿透到DB一定是不可接受的吗?如果有些场景允许穿透,应该怎么弄?<如果 DB 撑不住 redis 崩溃时的流量,那这种场景就是不可接受的。如果允许穿透那就代码实现了,比如先查询缓存,然后查数据库。>
  1. 多集群理解:按照业务划分集群时,比如按照电商,直播,游戏把账号集群划分成 3 个集群, 当电商的账号业务集群宕机; 流量会打到直播和游戏, 由于直播游戏的缓存中没有电商账号缓存,会直接请求 MySQL。为了解决这个问题, 后面的进化版本的算法,没太听懂。 是不是 不管什么业务,调用账号服务时, 按照一定的算法,分配到这三个账号服务集群, 每个账号集群都保留着所有业务的大部分账号缓存;,这样当一个集群宕机之后 , 其他两个集群承担流量之后, 只会有少部分请求会打到 MySQL?这样理解对吗?
  1. K8S 也有个多租户的概念,这个跟课上讲的多租户是不是有联系?
  1. 流量染色、中间件 shadow system 适配等使用中间件的方式来做基础设施处理,会不会导致在推广和升级的时候很困难(毕竟中间件的开发也是有迭代周期的,每次升级或者补充新功能,需要推动所有模块发布),这里为什么不采用 Service Mesh 的无侵入解决方案?如果采用 Service Mesh 需要注意什么?
  1. 客户端服务发现不是在同一个 name space 或 pod 里起 lb 那是怎么做直连的,耦合在代码吗
  1. 服务发现,消费者,在之前的架构中是怎么分布?消费者是 BFF?
  1. 刚才说的多集群都是服务的集群,想在了解一下服务后端的 cache 和 db 是怎么架构的?

柠檬: 分情况.

1.如果服务的数据是完全隔离的, 那就可以使用不同的 cache, db. 比如数据根据 id hash 到不同的集群进行存储, 读写.

2.使用隔离的数据, 但是底层通过同步机制进行双向同步.

3.使用隔离的数据, 但一处为写, 其他为读, 底层进行单向同步

4.使用一套数据源, 如果数据挂了, 所有服务也都不可用了, 大部分情况下, 数据源都是比较稳定的.

  1. K8S service 自动发现和外挂的自动发现在应用上有什么区别么(我之前知道的 zookeeper 是可以有接口维度注册。)

柠檬:

服务注册过程指的是在服务注册表中登记一个服务,以便让其它服务发现. 这两者都是这个含义. 首先需要服务注册中心, 然后需要服务注册, 其实是发现和访问.


不同点总结来看:

1.注册粒度不同, 一个是进程, 一个是 pod.

2. 访问方式不同, zk 的方式更多是直接 ip port 访问, 而 k8s 的访问经过层数更多.

3. k8s 的模式更为标准化与云原生. zk/etcd/consul/eureka/自研的方式各种各样, k8s 比较标准化.


类似于 zk 的服务注册需要服务自己去往 zk 的某个目录节点写入进程自己的信息(ip/port), 该目录节点作为服务名或者服务名的一部分. 且一般服务 A 通过 zk 拿到服务 B 的某个 ip, port 后直接连接, 进行调用.

k8s 的 service 代表的是符合某个 selector 的一系列 pod. k8s 的 pod 是注册在 etcd 中. 这两个与 zk 类似. k8s 的注册以 pod 为粒度注册, 且 k8s 的 service 访问模式有很多种.

集群内访问模式: 由 kube-proxy 组件和 Iptables 发现及转发流量.

向集群外暴露 Service: LoadBalancer. 外部的负载监听器监听 service 的 pod 变化, 然后配置负载均衡器.

https://developer.aliyun.com/article/728115

实际访问链路是什么样的呢?比如说从集群内部的一个 Client Pod3 去访问 Service,就类似于刚才所演示的一个效果。Client Pod3 首先通过 Coredns 这里去解析出 ServiceIP,Coredns 会返回给它 ServiceName 所对应的 service IP 是什么,这个 Client Pod3 就会拿这个 Service IP 去做请求,它的请求到宿主机的网络之后,就会被 kube-proxy 所配置的 iptables 或者 IPVS 去做一层拦截处理,之后去负载均衡到每一个实际的后端 pod 上面去,这样就实现了一个负载均衡以及服务发现。

对于外部的流量,比如说刚才通过公网访问的一个请求。它是通过外部的一个负载均衡器 Cloud Controller Manager 去监听 service 的变化之后,去配置的一个负载均衡器,然后转发到节点上的一个 NodePort 上面去,NodePort 也会经过 kube-proxy 的一个配置的一个 iptables,把 NodePort 的流量转换成 ClusterIP,紧接着转换成后端的一个 pod 的 IP 地址,去做负载均衡以及服务发现。这就是整个 K8s 服务发现以及 K8s Service 整体的结构。


此处我了解不深入. 请其他助教补充.


  1. 微服务之间的调用怎样保证操作的原子性呢?比如有用户服务、钱包服务、商品服务,下单之后,数据需要保证 1、钱包扣钱 2、商品下单 3、用户信息更改,同时完成。

柠檬: 首先大部分服务之间的数据相互独立. 其次大部分情况下, 数据存在不一致也正常. 比如用户头像, 昵称, 很多服务是可以做缓存的. 一旦需要考虑必须要一致的这个问题, 那就是个复杂问题了. 有以下等方法.

最大努力通知型: 基于唯一 id 号当场重试, 重试多次后失败. 提供接口查询, 校对.

TCC: 用户根据自己的业务场景实现 Try、Confirm 和 Cancel 三个操作;事务发起方在一阶段执行 Try 方式,在二阶段提交执行 Confirm 方法,二阶段回滚执行 Cancel 方法。

本地消息表: 本地事务与本地消息数据表一起插入, 由定时任务发送消息表中的数据到队列中.

事务消息: 本地事务的执行与消息发出去具有一致性, 有专门的事务消息中间件支持, 比如 rocketmq, 其实是上面本地消息表的一种演进.

  1. 多租户:代码层面的服务、数据层面的 DB/Cache 通过 shadow 隔离了,但是资源方面如何隔离,如何做到全链路压测不影响生产环境的资源呢?

柠檬: 存在全链路压测影响现网的情况, 一般应该在低峰比如凌晨的时候压测. 有的则将压测流量染色转入专门的压测环境, 需要所有的服务均支持.

  1. 云厂商的时候的多活,注意哪些多活,主要是可用区的多活吧

柠檬: 涉及到数据的话, 多活会很麻烦. 目前还比较少这么强大的组件.

此处我了解不深入. 请其他助教补充.

  1. 服务内部调用时,是否会用到 BFF 的请求需要一个请求调用多个接口

答:这应该是一种常态,即 BFF 会调用多个服务来完成某一个请求。本质上来说,BFF 是一种特殊的聚合服务。

  1. 一个评论服务用户信息部分 是在评论服务聚合还是在 bff 聚合?

答:评论服务不维护任何的用户信息,它只拥有用户的 ID,那么聚合只能在 BFF 处聚合,由 BFF 去拿到用户的基本信息(如用户名,昵称),而后聚合结果之后返回给用户。

  1. 兼容的多版本 API 的实现:是不是每个版本都有个独立的微服务,然后根据 API 版本打到对应版本的微服务?

答:业界做法是非常多样的。普遍有两种:一种就是你提到的这种,不同的版本直接部署成独立的服务,并且是独立的实例。这种做法的好处是隔离性很强,互不影响,代价是运维复杂;另外一种实践是,不同版本部署在同一个微服务,但是在请求里面会有版本标识,服务器在收到请求之后根据版本来断定应该使用哪个实现。这个需要微服务框架的支持。

如果微服务框架在服务发现过程,就支持版本,也就是,当你想调用某个版本的服务的时候,你只能发现该版本的服务,那么从逻辑上来说,不同版本的服务就是彻底不同的服务。而在实际部署中,是否是单独部署,就不太重要了。

  1. 续第一个课 105 题,就是有关 CQRS 部分,文稿和审核, 审核那么复杂为什么不直接把审核部分分离出来?

答:你说的分离是指接口分离还是审核整个分离?一般来说,审核都是一个单独的服务——大公司应该叫做审核平台,负责对外屏蔽掉审核细节。例如是机器审核还是人工审核,机器审核之后要不要人工审核。业务要做的就是把审核的内容推过去,而后去审核平台请求一个审核流程就可以。如果涉及到CQRS,我理解的,这里的意思是,和审核平台交互的地方为什么不分离?分离会更好。


  1. 关于课程中说的 eruka 的新老数据按照时间戳进行覆盖,实际上服务器时间是有误差的,那么有一定的概率误删吗?还是说这里问题实践中,发生的概率不那么高?

答:从概率上来说的确是微乎其微。这个问题涉及到分布式系统中一个非常核心的问题,即分布式系统实例时间同步的问题。一般来说,机器都要定期校准自己的时间,所以理论上的确存在这种误差,只不过是非常小的。

  1. vim 和 goland 推荐哪种?工程化大都推荐 Goland,这时候用 vim 协作会有问题吗?<既然能问这个问题那么就是 goland 了,vim 除非你能





































































  1. protocol buffer 多个微服务间的共享,git submodule 当初考虑过吗?pb 定义的代码有版本之分吗?
  1. 老师,大数据分析的结果(比如推荐,前人千面)怎么接入当前的微服务体系,
  1. 假如我有两个库 A 和 B,A 库中要查询 id,name,age 这三个字段,B 库要查询 id, use_time 这两个字段,同时要满足 age > 30,use_time > 100 这两个查询条件,同时还要满足分页需求,这样怎么查询?(楼下和我似乎是一样的问题)(加冗余字段可以部分解决,但是如果我的筛选条件更多,需要在 B1,B2,B3……多个库中同时做筛选,B1,B2,B3 这些库中的 ID 和 A 库中的 ID 是对应的,这种跨服务,多条件,需要分页(获取总页数,当前页数)的查询有什么办法吗)
  1. 新旧系统上线,用 API 网关自动发现服务上线,如果服务上线直接转发请求到新节点,没发现有这个服务的直接转发到旧代码,比写一大堆 rewirte 好吧?也是一个接口一个接口切

如果是这样的话,则需要看是否新旧服务都是用同一个 db。如果异构数据库,可能会造成数据混乱,增加对数成本与风险。同构则无所谓。

  1. 如何设计多租户的流量标签的自动管理,当有新的标签需要测试时,可以实现自动分发。代码规范上是否需要提前设计好一套规范,每个服务开发时需要遵循这套标识。

需要在 PaaS 平台上进行支持,建基于 k8s 上的标签,建立用户与标签的关联关系。客户端请求时,获取用户的标签,放入请求,从链路中透传。

  1. 全链路压测 DB 实例如果和生产环境共用,会不会因为压测负载过高把生产环境搞挂?

建议通过生产 DB 产生一个影子库进行压测。如果使用生产库,会出现脏数据。产品与运营小姐姐可能会发飙。

  1. 多集群,互蹭解决热点数据穿透问题,那最终不就变成了不是某个集群针对某个业务的设计初衷么

课上的例子是:原先的账号服务,热点都缓存在服务里头。并且原先账号之间是分集群隔离部署的。 比如游戏一个集群, 电商一个。 当某一天电商集群突然挂了,然后就把流量打到游戏那个集群,会发现玩电商的那波人,在游戏里头的缓存都没有,所以就造成了热点穿透的问题。

最后解决的方案是:把所有集群的用户都缓存起来。 这样后面即使某个集群挂了,也可以用另外一个集群。

  1. 老师好,服务发现的客户端发现模式,是还需要一个注册中心来保存所有服务的真实链接地址,就类似 dns 解析域名到 ip 上。那这个注册应该岂不还是没有去中心化?谢谢

现在可以选择的开源注册中心,基本上都可以通过部署模型上达到分布式的效果。但不一样的中间件达到的不一样的可用性标准。

  1. 平滑退出后,新程序的发布是通过 k8s 来实现的么?
  1. 怎样看待,sre 谷歌运维解密中讲到的错误预算
  1. A 服务起了 3 个副本,注册到注册中心,B 服务调用 A 服务,向注册中心拿 A 服务的 ip 列表,这个拿的过程是 B 服务自己写代码实现吗?拿到 A 服务的 ip 列表后,具体请求哪个 ip 的负载均衡算法,也是要 B 服务自己写代码实现吗?
  1. consul 自带的有健康检查功能,而课上讲的 B 服务会调用它依赖的 A 服务的 healthcheck 接口,这种 B 服务自己实现检查它所有依赖服务的 healthcheck,是为了弥补你们注册中心没有 healthcheck 这种情况吗?那 B 服务是不是要定时调用所有它依赖服务的 healthcheck 接口?
  1. service mesh 为什么对大多数公司没有收益,是因为:
  1. 开销大,是因为进程间通信造成的开销大么
  1. 复杂:可能接触的不算多,哪里复杂呢,是要在 mesh 中做限流、容灾比较复杂么

客户端服务发现+自身实现 LB 和服务端服务发现,在请求次数上并没有减少吧,只是做到了去中心化吧,因为都是三次请求:

  1. 服务端服务发现:请求到 LB、LB 到服务发现、LB 到后端
  1. 客户端服务发现+自身实现 LB:请求到服务发现、请求到 LB、LB 到后端
  1. Provider 服务到 Discovery 注册后,Consumer 服务如何从 Discovery 获取 Provider 信息(是 Consumer 主动拉?还是 Discovery 推)?如果主动拉需不需要考虑 consumer 同时发起拉请求可能会使得 Discovery 处理不过来的问题?如果是推一般采用什么策略(推送的时机)?

不同得服务发现中间件在细节上都有细微差异,从性价比上来讲但是都围绕着 AP 理论。参考 lesson2 中 eueka 中实现,consumer-side 会在启动时向服务发现中心订阅 Provider-side 连接信息,为了避免过于频繁得向中心请求压力,选择了 30s 长连接得 patch 方式打包这段时间得更新信息,这样平滑了拉取压力,同时有 heath check 帮助下保证可用(同时也可选不同的 poll-period 来避免错峰 )。

  1. 毛老师好,我有两个问题想请教一下

1)、微服务后 b 站是如何解决分布式事务的?

2)、微服务后要跨多个服务查询数据,是怎么实现之前单个数据库的 join、group by、order by 功能的?是将各个微服务查询出来的数据放在内存中然后用代码实现 join、group by、order by 的功能吗?这样做会不会很复杂?

柠檬: 1. 可参照 47. 同时也请毛老师解答

  1. 复杂排序可以采用 es 来同步数据用于查询, 简单的排序可用 redis, 服务只存储自己的领域数据, 比如榜单, 就只存 uid 和分数. 像头像, 昵称这些, 从其他服务拉取组装. 需要转变一下思维方式, 不是所有的业务都需要 db 的, 不是所有数据都需要复杂的 join, order, group 等功能, 业务规模大, 基本意味着单服务逻辑会简单. 对于大部分服务, 使用的反而是 kv 数据.
  1. API Gateway->BFF->Service:API Gateway 也是一个微服务?另外老师说 API Gateway 里做隔离、限流,负载均衡等可用性,是不是除了 API Gateway,下面的像 BFF、Service 就只需要关注业务逻辑了,不用管什么限流等了吗?

首先要理解 API Gateway(A)、BFF(B)、service(S)之间的角色定义,比如限流,A 是系统服务的入口、B 是业务聚合的服务、C 是数据源。那么限流可以是为"发言"这个协议做限流,那么 B 就是「具体哪个 UID」发言做限流、C 就是为「发言计数信息」做限流。分布式系统中没有统一的答案,也没有准确的规则,一切都需要按照实际场景因地制宜。

  1. 请问微服务之前怎么实现事务处理的?

柠檬: 见 47 问

  1. 对于使用多个节点来缓解压力,总需要一个负载均衡来分配,那这个负载均衡就需要承受全部压力,即使这个负载均衡也多节点,那也需要一个类似 LVS 的东西,来分配给多个负载均衡,它就要承受所有的压力,它如何承受得住所有压力的呢?
  1. grpc 的健康检查是服务提供者与调用者的检查,服务调用者也会向 eureka 发送健康检查,eureka 也会定期发送检测到 provider 者检测服务可用性,我这样理解对么?
  1. 大量的 Consumer 与 Provide 进行 healthcheck,如果使用子集算法对 Provide 节点取子集不应该会更危险吗?
  1. 分层结构中的 API-gateway 可以理解为就是 k8s 中的



毛剑老师来答:


  1. 毛老师,能不能推荐几个微服务实践项目代码,可以用来学习
  1. 毛老师,源码阅读有没有好的切入点建议,还是直接硬啃
  1. 老师可以讲讲 grpc 最新用的 xds 嘛?网上都没找到例子,只有协议描述,但是没有 get 到点。
  1. B 站只用了 k8s 的容器编排吗?还用了其它哪些功能?
  1. 老师可以讲一下为啥不用 istio?istio 也提供了基于 envoy 实现的 sidecar,可以提供染色,熔断,金丝雀发布,而且是非侵入式的,改改配置文件就能实现,它不香吗?
  1. 毛老师,可以分享你们标准化启动 goruntinue 是怎么做的吗?谢谢
  1. b 站数据库 db 方面数据量最大的表有存多少数据,查起来会不会比较慢如果没有分表的话
  1. 实战项目,比如在这一节最后讲的多租户测试环境,有没有一个实际的代码环境去演练下
  1. 公司使用 java 的 springcloud 目前是想用 golang 去慢慢的替换,注册中心使用的 eureka 请问老师我想把 golang 的服务注册到 eureka 应该注意什么。还有后面的逐步迁移有什么需要注意的地方
  1. 为什么要多集群要独占缓存然后订阅 binlog,多集群共享一个缓存不行么。独享的话如果多集群质检上了 redis 怎么办